home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1994 / 8 / 05 / term-4.0-source.lha / termEmulation.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-08  |  46.8 KB  |  2,768 lines

  1. /*
  2. **    termEmulation.c
  3. **
  4. **    Terminal emulation (parsing and processing) routines
  5. **
  6. **    Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11. #include "termEmulationProcess.h"
  12.  
  13.     /* One of the emulation callback routines. */
  14.  
  15. typedef VOID (*  EPTR)(STRPTR Buffer);
  16.  
  17.     /* This structure describes an ANSI control sequence. */
  18.  
  19. struct ControlCode
  20. {
  21.     UBYTE    FirstChar;
  22.     STRPTR    Match;
  23.     UBYTE    LastChar;
  24.  
  25.     BYTE    ExactSize;
  26.     EPTR    Func;
  27. };
  28.  
  29.     /* How many characters we will keep in the scan buffer. */
  30.  
  31. #define MAX_SCAN_SIZE    256
  32.  
  33.     /* Flag indicating whether the cursor has already been
  34.      * erased or not.
  35.      */
  36.  
  37. STATIC BYTE        CursorEnabled = FALSE;
  38.  
  39.     /* Cursor handling data. */
  40.  
  41. STATIC WORD        LastCursorX = -1,
  42.             LastCursorY = -1;
  43.  
  44. STATIC LONG        DestX,
  45.             DestY,
  46.             XSize;
  47.  
  48. STATIC BYTE        CursorGhosted = FALSE;
  49.  
  50.     /* Backup style. */
  51.  
  52. STATIC UBYTE        StyleType = FS_NORMAL;
  53.  
  54.     /* Cursor backup data. */
  55.  
  56. STATIC struct CursorData CursorBackup;
  57.  
  58.     /* A couple of internally referenced variables. */
  59.  
  60. STATIC BYTE        CharsInBuffer    = 0,
  61.             ScanStep    = 0;
  62. STATIC UBYTE __far    SaveBuffer[MAX_SCAN_SIZE + 1];
  63.  
  64.     /* Character access tables. */
  65.  
  66. STATIC UBYTE __far Table0[256] =
  67. {
  68.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  69.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  70.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  71.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  72.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  73.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  74.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  75.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  76.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  77.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  78.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  79.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  80.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  81.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  82.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  83.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  84. };
  85.  
  86. STATIC UBYTE __far Table1[256] =
  87. {
  88.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  89.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  90.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  91.     1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,
  92.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  93.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  94.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  95.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  96.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  97.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  98.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  99.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  100.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  101.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  102.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  103.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  104. };
  105.  
  106. STATIC UBYTE __far Table2[256] =
  107. {
  108.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  109.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  110.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  111.     1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,
  112.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  113.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  114.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  115.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  116.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  117.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  118.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  119.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  120.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  121.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  122.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  123.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  124. };
  125.  
  126. STATIC UBYTE __far Table3[256] =
  127. {
  128.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  129.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  130.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  131.     1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,
  132.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  133.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  134.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  135.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  136.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  137.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  138.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  139.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  140.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  141.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  142.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  143.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  144. };
  145.  
  146. STATIC UBYTE __far Table4[256] =
  147. {
  148.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  149.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  150.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  151.     1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,
  152.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  153.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  154.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  155.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  156.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  157.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  158.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  159.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  160.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  161.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  162.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  163.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  164. };
  165.  
  166.     /* This follows the control code information. */
  167.  
  168. struct ControlCode ANSICode[] =
  169. {
  170.     /* Single Character Sequences. */
  171.  
  172.     'D',    Table0,     0 ,    1,    (EPTR)CursorScrollDown,
  173.     'M',    Table0,     0 ,    1,    (EPTR)CursorScrollUp,
  174.     'E',    Table0,     0 ,    1,    (EPTR)NextLine,
  175.     '7',    Table0,     0 ,    1,    (EPTR)SaveCursor,
  176.     '8',    Table0,     0 ,    1,    (EPTR)LoadCursor,
  177.     '=',    Table0,     0 ,    1,    (EPTR)NumericAppMode,
  178.     '>',    Table0,     0 ,    1,    (EPTR)NumericAppMode,
  179.     'N',    Table0,     0 ,    1,    (EPTR)Ignore,
  180.     'O',    Table0,     0 ,    1,    (EPTR)Ignore,
  181.     'H',    Table0,     0 ,    1,    (EPTR)SetTab,
  182.     'Z',    Table0,     0 ,    1,    (EPTR)RequestTerminal,
  183.     'c',    Table0,     0 ,    1,    (EPTR)Reset,
  184.     '<',    Table0,     0 ,    1,    (EPTR)Ignore,
  185.     '~',    Table0,     0 ,    1,    (EPTR)Ignore,
  186.     'n',    Table0,     0 ,    1,    (EPTR)Ignore,
  187.     '}',    Table0,     0 ,    1,    (EPTR)Ignore,
  188.     'o',    Table0,     0 ,    1,    (EPTR)Ignore,
  189.     '|',    Table0,     0 ,    1,    (EPTR)Ignore,
  190.  
  191.     /* Double Character Sequences. */
  192.  
  193.     '[',    Table0,    's',    2,    (EPTR)SaveCursor,
  194.     '[',    Table0,    'u',    2,    (EPTR)LoadCursor,
  195.     '(',    Table0,    'A',    2,    (EPTR)FontStuff,
  196.     '(',    Table0,    'B',    2,    (EPTR)FontStuff,
  197.     '(',    Table0,    '0',    2,    (EPTR)FontStuff,
  198.     ')',    Table0,    'A',    2,    (EPTR)FontStuff,
  199.     ')',    Table0,    'B',    2,    (EPTR)FontStuff,
  200.     ')',    Table0,    '0',    2,    (EPTR)FontStuff,
  201.     '#',    Table0,    '3',    2,    (EPTR)ScaleFont,
  202.     '#',    Table0,    '4',    2,    (EPTR)ScaleFont,
  203.     '#',    Table0,    '5',    2,    (EPTR)ScaleFont,
  204.     '#',    Table0,    '6',    2,    (EPTR)ScaleFont,
  205.     '#',    Table0,    '8',    2,    (EPTR)AlignmentTest,
  206.     ' ',    Table0,    'F',    2,    (EPTR)Ignore,
  207.     ' ',    Table0,    'G',    2,    (EPTR)Ignore,
  208.  
  209.     /* Multiple Character Sequence. */
  210.  
  211.     '[',    Table3,    'i',    0,    (EPTR)PrinterController,
  212.  
  213.     '[',    Table3,    'n',    0,    (EPTR)RequestInformation,
  214.     '[',    Table3,    'c',    0,    (EPTR)RequestTerminal,
  215.     '[',    Table3,    'h',    0,    (EPTR)SetSomething,
  216.     '[',    Table3,    'l',    0,    (EPTR)SetSomething,
  217.  
  218.     '[',    Table4,    'h',    0,    (EPTR)Ignore,
  219.  
  220.     '[',    Table1,    'A',    0,    (EPTR)MoveCursor,
  221.     '[',    Table1,    'B',    0,    (EPTR)MoveCursor,
  222.     '[',    Table1,    'C',    0,    (EPTR)MoveCursor,
  223.     '[',    Table1,    'D',    0,    (EPTR)MoveCursor,
  224.     '[',    Table1,    'G',    0,    (EPTR)MoveColumn,
  225.     '[',    Table1,    'K',    0,    (EPTR)EraseLine,
  226.     '[',    Table1,    'J',    0,    (EPTR)EraseScreen,
  227.     '[',    Table1,    'P',    0,    (EPTR)EraseCharacters,
  228.     '[',    Table1,    '@',    0,    (EPTR)InsertCharacters,
  229.     '[',    Table1,    'L',    0,    (EPTR)InsertLine,
  230.     '[',    Table1,    'M',    0,    (EPTR)ClearLine,
  231.     '[',    Table1,    'g',    0,    (EPTR)SetTabs,
  232.     '[',    Table1,    'q',    0,    (EPTR)Ignore,
  233.  
  234.     '[',    Table2,    'H',    0,    (EPTR)SetAbsolutePosition,
  235.     '[',    Table2,    'f',    0,    (EPTR)SetAbsolutePosition,
  236.     '[',    Table2,    'm',    0,    (EPTR)SetAttributes,
  237.     '[',    Table2,    'y',    0,    (EPTR)Ignore,
  238.     '[',    Table2,    'r',    0,    (EPTR)SetRegion,
  239.  
  240.     '[',    Table1,    'S',    0,    (EPTR)ScrollUp,
  241.     '[',    Table1,    'T',    0,    (EPTR)ScrollDown
  242. };
  243.  
  244. STATIC WORD NumCodes = sizeof(ANSICode) / sizeof(struct ControlCode);
  245.  
  246.     /* GetFontWidth():
  247.      *
  248.      *    Get the font width of the current line.
  249.      */
  250.  
  251. STATIC WORD
  252. GetFontWidth(VOID)
  253. {
  254.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  255.     {
  256.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  257.             return((WORD)(TextFontWidth / 2));
  258.         else
  259.             return(TextFontWidth);
  260.     }
  261.     else
  262.     {
  263.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  264.             return(TextFontWidth);
  265.         else
  266.             return((WORD)(TextFontWidth * 2));
  267.     }
  268. }
  269.  
  270.     /* ColourValue(UWORD Colour):
  271.      *
  272.      *    Calculate the value of a given colour (brightness).
  273.      */
  274.  
  275. STATIC WORD __inline
  276. ColourValue(UWORD Colour)
  277. {
  278.     BYTE    Red,Green,Blue;
  279.     WORD    Sum;
  280.  
  281.     Red    =  Colour >> 8;
  282.     Green    = (Colour >> 4) & 0xF;
  283.     Blue    =  Colour       & 0xF;
  284.  
  285.     Sum = (Red + Green + Blue) / 3;
  286.  
  287.     return(Sum);
  288. }
  289.  
  290.     /* ScrollRegion(WORD Direction):
  291.      *
  292.      *    Scroll the current scroll region up or down.
  293.      */
  294.  
  295. VOID __regargs
  296. ScrollRegion(WORD Direction)
  297. {
  298.     WORD RegionTop,RegionBottom,RegionLines;
  299.     LONG Dir,MinY,MaxY;
  300.  
  301.     if(Direction < 0)
  302.         Dir = -Direction;
  303.     else
  304.         Dir = Direction;
  305.  
  306.     if(RegionSet)
  307.     {
  308.         MinY         = MUL_Y(Top);
  309.         MaxY        = MUL_Y(Bottom + 1) - 1;
  310.  
  311.         RegionTop    = Top;
  312.         RegionBottom    = Bottom + 1;
  313.         RegionLines    = Bottom - Top + 1;
  314.     }
  315.     else
  316.     {
  317.         MinY        = 0;
  318.         MaxY         = MUL_Y(LastLine + 1) - 1;
  319.  
  320.         RegionTop    = 0;
  321.         RegionBottom    = LastLine + 1;
  322.         RegionLines    = LastLine + 1;
  323.     }
  324.  
  325.     BackupRender();
  326.  
  327.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  328.  
  329.     if(Config -> EmulationConfig -> ScrollMode == SCROLL_JUMP || (TextFontHeight & 1))
  330.     {
  331.         if(Dir > RegionLines)
  332.             ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  333.         else
  334.         {
  335.             if(Direction > 0)
  336.                 ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,FALSE);
  337.             else
  338.                 ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,FALSE);
  339.         }
  340.     }
  341.     else
  342.     {
  343.         if(Direction > 0)
  344.             ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,TRUE);
  345.         else
  346.             ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,TRUE);
  347.     }
  348.  
  349.     BackupRender();
  350. }
  351.  
  352.     /* LastChar(STRPTR Buffer):
  353.      *
  354.      *    Return the last character in a string.
  355.      */
  356.  
  357. STATIC UBYTE __inline
  358. LastChar(STRPTR Buffer)
  359. {
  360.     WORD Offset = 0;
  361.  
  362.     while(Buffer[Offset])
  363.         Offset++;
  364.  
  365.     return(Buffer[Offset - 1]);
  366. }
  367.  
  368.     /* ReadValue(STRPTR Buffer,BYTE *Value):
  369.      *
  370.      *    Parse a buffer for numbers and return a pointer
  371.      *    to the next buffer element to contain additional
  372.      *    information.
  373.      */
  374.  
  375. STATIC STRPTR __inline
  376. ReadValue(STRPTR Buffer,WORD *Value)
  377. {
  378.     while(*Buffer && *Buffer != ';' && (*Buffer < '0' || *Buffer > '9'))
  379.         Buffer++;
  380.  
  381.     if(*Buffer)
  382.     {
  383.         *Value = 0;
  384.  
  385.         while(*Buffer >= '0' && *Buffer <= '9')
  386.             *Value = (*Value * 10) + (*Buffer++ - '0');
  387.     }
  388.     else
  389.         *Value = -1;
  390.  
  391.     if(*Buffer == ';' || *Buffer == ' ')
  392.         return(Buffer + 1);
  393.     else
  394.         return(NULL);
  395. }
  396.  
  397. STATIC VOID __regargs
  398. EmulationSerWrite(STRPTR String,LONG Length)
  399. {
  400.     if(SysBase -> ThisTask == SpecialQueue -> SigTask)
  401.         SerWrite(String,Length);
  402.     else
  403.     {
  404.         struct DataMsg *Msg;
  405.  
  406.         if(Length == -1)
  407.             Length = strlen(String);
  408.  
  409.         if(Msg = (struct DataMsg *)CreateMsgItem(sizeof(struct DataMsg) + Length + 1))
  410.         {
  411.             Msg -> Type = DATAMSGTYPE_WRITE;
  412.             Msg -> Data = (STRPTR)(Msg + 1);
  413.             Msg -> Size = Length;
  414.  
  415.             CopyMem(String,Msg -> Data,Length + 1);
  416.  
  417.             PutMsgItem(SpecialQueue,(struct MsgItem *)Msg);
  418.         }
  419.     }
  420. }
  421.  
  422.     /* DoCancel():
  423.      *
  424.      *    Cancel any currently scanned sequence.
  425.      */
  426.  
  427. BYTE 
  428. DoCancel()
  429. {
  430.     InSequence    = FALSE;
  431.     CharsInBuffer    = ScanStep = 0;
  432.  
  433.     return(FALSE);
  434. }
  435.  
  436.     /* CSIFake():
  437.      *
  438.      *    This routine was added to support 8-bit control
  439.      *    sequences introduced by a CSI character.
  440.      */
  441.  
  442. VOID
  443. CSIFake()
  444. {
  445.         /* Reset scanner */
  446.  
  447.     DoCancel();
  448.  
  449.         /* Perform as if ESC [ had been transmitted. */
  450.  
  451.     InSequence = ParseCode('[');
  452. }
  453.  
  454.     /* ParseCode(UBYTE c):
  455.      *
  456.      *    Input:    A character to be passed through the ANSI code
  457.      *        parser.
  458.      *
  459.      *    Output:    FALSE if input characters did form a valid ANSI
  460.      *        control sequence or if input characters did not
  461.      *        form an ANSI control sequence at all.
  462.      *
  463.      *        TRUE if input characters did possibly introduce
  464.      *        a valid ANSI control sequence.
  465.      */
  466.  
  467. BYTE 
  468. ParseCode(UBYTE c)
  469. {
  470.         /* ScanStep = 0:    This is the first character
  471.          *            to introduce a control sequence.
  472.          */
  473.  
  474.     if(!ScanStep)
  475.     {
  476.         register WORD i;
  477.  
  478.             /* Scan all available codes and try to find
  479.              * a match.
  480.              */
  481.  
  482.         for(i = 0 ; i < NumCodes ; i++)
  483.         {
  484.                 /* This character may introduce a
  485.                  * control sequence.
  486.                  */
  487.  
  488.             if(ANSICode[i] . FirstChar == c)
  489.             {
  490.                     /* If this is a single
  491.                      * character control sequence
  492.                      * call the approriate function
  493.                      * and exit immediately.
  494.                      */
  495.  
  496.                 if(ANSICode[i] . ExactSize == 1)
  497.                 {
  498.                     if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  499.                     {
  500.                         SaveBuffer[CharsInBuffer++] = c;
  501.                         SaveBuffer[CharsInBuffer  ] = 0;
  502.  
  503.                         (*ANSICode[i] . Func)(SaveBuffer);
  504.                     }
  505.  
  506.                     CharsInBuffer = ScanStep = 0;
  507.  
  508.                     return(FALSE);
  509.                 }
  510.                 else
  511.                 {
  512.                         /* The length of this control
  513.                          * sequence is greater than
  514.                          * a single character. Save
  515.                          * the input character and
  516.                          * return.
  517.                          */
  518.  
  519.                     ScanStep = i;
  520.  
  521.                     SaveBuffer[CharsInBuffer++] = c;
  522.  
  523.                     return(TRUE);
  524.                 }
  525.             }
  526.         }
  527.     }
  528.     else
  529.     {
  530.         if(CharsInBuffer < MAX_SCAN_SIZE)
  531.         {
  532.             register WORD i;
  533.  
  534.                 /* Scan the remaining codes for a match. */
  535.  
  536.             for(i = ScanStep ; i < NumCodes ; i++)
  537.             {
  538.                     /* This sequence begins with the
  539.                      * same character the parser was
  540.                      * initialized with, so let's take
  541.                      * a look at it.
  542.                      */
  543.  
  544.                 if(ANSICode[i] . FirstChar == SaveBuffer[0])
  545.                 {
  546.                         /* This character is supposed to
  547.                          * terminate the sequence, so exit.
  548.                          */
  549.  
  550.                     if(ANSICode[i] . LastChar == c)
  551.                     {
  552.                         if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  553.                         {
  554.                             SaveBuffer[CharsInBuffer++] = c;
  555.                             SaveBuffer[CharsInBuffer  ] = 0;
  556.  
  557.                             (*ANSICode[i] . Func)(SaveBuffer);
  558.                         }
  559.  
  560.                         CharsInBuffer = ScanStep = 0;
  561.  
  562.                         return(FALSE);
  563.                     }
  564.                     else
  565.                     {
  566.                             /* If this character is part of
  567.                              * a legal sequence store it
  568.                              * and return.
  569.                              */
  570.  
  571.                         if(ANSICode[i] . Match[c])
  572.                         {
  573.                             ScanStep = i;
  574.  
  575.                             SaveBuffer[CharsInBuffer++] = c;
  576.  
  577.                             return(TRUE);
  578.                         }
  579.                     }
  580.                 }
  581.             }
  582.         }
  583.     }
  584.  
  585.         /* Return failure. */
  586.  
  587.     CharsInBuffer = ScanStep = 0;
  588.  
  589.     return(FALSE);
  590. }
  591.  
  592.     /* ToggleCursor():
  593.      *
  594.      *    (Re)draw the cursor image.
  595.      */
  596.  
  597. VOID
  598. ToggleCursor()
  599. {
  600.     ObtainTerminal();
  601.  
  602.     if(Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL)
  603.     {
  604.         UWORD    OldAPen    = ReadAPen(RPort),
  605.             OldBPen    = ReadBPen(RPort),
  606.             OldDrMd    = ReadDrMd(RPort),
  607.  
  608.             Left    = WindowLeft + DestX,
  609.             Top    = WindowTop + DestY;
  610.  
  611.         if(Kick30)
  612.         {
  613.             SetABPenDrMd(RPort,DepthMask,OldBPen,JAM1 | COMPLEMENT);
  614.  
  615.             if(UseMasking)
  616.             {
  617.                 UBYTE Mask = RPort -> Mask;
  618.  
  619.                 SetWrMsk(RPort,DepthMask);
  620.  
  621.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  622.  
  623.                 SetWrMsk(RPort,Mask);
  624.             }
  625.             else
  626.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  627.  
  628.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  629.         }
  630.         else
  631.         {
  632.             SetAPen(RPort,DepthMask);
  633.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  634.  
  635.             if(UseMasking)
  636.             {
  637.                 UBYTE Mask = RPort -> Mask;
  638.  
  639.                 SetWrMsk(RPort,DepthMask);
  640.  
  641.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  642.  
  643.                 SetWrMsk(RPort,Mask);
  644.             }
  645.             else
  646.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  647.  
  648.             SetAPen(RPort,OldAPen);
  649.             SetDrMd(RPort,OldDrMd);
  650.         }
  651.     }
  652.  
  653.     ReleaseTerminal();
  654. }
  655.  
  656.     /* NormalCursor():
  657.      *
  658.      *    Enable normal (filled) cursor image.
  659.      */
  660.  
  661. VOID
  662. NormalCursor()
  663. {
  664.     ObtainTerminal();
  665.  
  666.     if(CursorGhosted)
  667.     {
  668.         if(CursorEnabled)
  669.         {
  670.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  671.  
  672.             ToggleCursor();
  673.  
  674.             SetAfPt(RPort,NULL,0);
  675.  
  676.             ToggleCursor();
  677.         }
  678.  
  679.         CursorGhosted = FALSE;
  680.     }
  681.  
  682.     ReleaseTerminal();
  683. }
  684.  
  685.     /* GhostCursor():
  686.      *
  687.      *    Enable ghosted (checkered) cursor image.
  688.      */
  689.  
  690. VOID
  691. GhostCursor()
  692. {
  693.     ObtainTerminal();
  694.  
  695.     if(!CursorGhosted)
  696.     {
  697.         if(CursorEnabled)
  698.         {
  699.             ToggleCursor();
  700.  
  701.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  702.  
  703.             ToggleCursor();
  704.  
  705.             SetAfPt(RPort,NULL,0);
  706.         }
  707.  
  708.         CursorGhosted = TRUE;
  709.     }
  710.  
  711.     ReleaseTerminal();
  712. }
  713.  
  714.     /* ClipBlitCursor(UBYTE DoClip,UBYTE DoMove):
  715.      *
  716.      *    Change the appearance of the cursor.
  717.      */
  718.  
  719. VOID __regargs
  720. ClipBlitCursor(UBYTE DoClip,UBYTE DoMove)
  721. {
  722.     ObtainTerminal();
  723.  
  724.     if(DoClip || DoMove)
  725.     {
  726.         if(CursorY != LastCursorY || CursorX != LastCursorX)
  727.         {
  728.             STATIC LONG X,Y,Column;
  729.  
  730.             if(CursorY != LastCursorY)
  731.             {
  732.                 if(CursorY > LastLine)
  733.                     Y = LastLine;
  734.                 else
  735.                 {
  736.                     if(CursorY < 0)
  737.                         Y = 0;
  738.                     else
  739.                         Y = CursorY;
  740.                 }
  741.  
  742.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  743.                     Column = LastColumn;
  744.                 else
  745.                     Column = ((LastColumn + 1) / 2) - 1;
  746.  
  747.                 DestY = MUL_Y(Y);
  748.  
  749.                 LastCursorY = CursorY;
  750.             }
  751.  
  752.             LastCursorX = CursorX;
  753.  
  754.             if(CursorX > Column)
  755.                 X = Column;
  756.             else
  757.             {
  758.                 if(CursorX < 0)
  759.                     X = 0;
  760.                 else
  761.                     X = CursorX;
  762.             }
  763.  
  764.             if(Config -> EmulationConfig -> FontScale == SCALE_NORMAL)
  765.             {
  766.                 if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  767.                 {
  768.                     DestX = MUL_X(X);
  769.                     XSize = TextFontWidth;
  770.                 }
  771.                 else
  772.                 {
  773.                     DestX = MUL_X(X) * 2;
  774.                     XSize = TextFontWidth * 2;
  775.  
  776.                     if(X > ((LastColumn + 1) / 2) - 1)
  777.                         X = ((LastColumn + 1) / 2) - 1;
  778.                 }
  779.             }
  780.             else
  781.             {
  782.                 if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  783.                 {
  784.                     DestX = MUL_X(X) / 2;
  785.                     XSize = TextFontWidth / 2;
  786.                 }
  787.                 else
  788.                 {
  789.                     DestX = MUL_X(X);
  790.                     XSize = TextFontWidth;
  791.  
  792.                     if(X > ((LastColumn + 1) / 2) - 1)
  793.                         X = ((LastColumn + 1) / 2) - 1;
  794.                 }
  795.             }
  796.         }
  797.  
  798.         if(DoMove)
  799.             Move(RPort,WindowLeft + DestX,WindowTop + DestY + TextFontBase);
  800.  
  801.         if(DoClip)
  802.         {
  803.             if(CursorGhosted)
  804.             {
  805.                 SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  806.  
  807.                 ToggleCursor();
  808.  
  809.                 SetAfPt(RPort,NULL,0);
  810.             }
  811.             else
  812.                 ToggleCursor();
  813.         }
  814.     }
  815.  
  816.     ReleaseTerminal();
  817. }
  818.  
  819.     /* ClearCursor():
  820.      *
  821.      *    Clear the cursor image.
  822.      */
  823.  
  824. VOID
  825. ClearCursor()
  826. {
  827.     ObtainTerminal();
  828.  
  829.     if(CursorEnabled)
  830.     {
  831.         ClipBlitCursor(TRUE,FALSE);
  832.  
  833.         CursorEnabled = FALSE;
  834.     }
  835.  
  836.     ReleaseTerminal();
  837. }
  838.  
  839.     /* DrawCursor():
  840.      *
  841.      *    Explicitely (re-)draw the cursor image.
  842.      */
  843.  
  844. VOID
  845. DrawCursor()
  846. {
  847.     ObtainTerminal();
  848.  
  849.     if(!CursorEnabled)
  850.     {
  851.         ClipBlitCursor(TRUE,FALSE);
  852.  
  853.         CursorEnabled = TRUE;
  854.     }
  855.  
  856.     ReleaseTerminal();
  857. }
  858.  
  859.     /* BackupRender():
  860.      *
  861.      *    Save current draw modes, pen and position or restore
  862.      *    the data.
  863.      */
  864.  
  865. VOID
  866. BackupRender()
  867. {
  868.     STATIC BYTE    Called = FALSE;
  869.     STATIC UBYTE    DrMd,
  870.             FgPen,
  871.             BgPen;
  872.     STATIC UWORD    OldX,OldY;
  873.     STATIC UBYTE    Style;
  874.  
  875.     if(!Called)
  876.     {
  877.         DrMd    = ReadDrMd(RPort);
  878.         FgPen    = ReadAPen(RPort);
  879.         BgPen    = ReadBPen(RPort);
  880.  
  881.         OldX    = RPort -> cp_x - WindowLeft;
  882.         OldY    = RPort -> cp_y - WindowTop;
  883.  
  884.         Style    = StyleType;
  885.  
  886.         Called    = TRUE;
  887.     }
  888.     else
  889.     {
  890.         if(ReadDrMd(RPort) != DrMd)
  891.             SetDrMd(RPort,DrMd);
  892.  
  893.         if(ReadAPen(RPort) != FgPen)
  894.             SetAPen(RPort,FgPen);
  895.  
  896.         if(ReadBPen(RPort) != BgPen)
  897.             SetBPen(RPort,BgPen);
  898.  
  899.         Move(RPort,OldX + WindowLeft,OldY + WindowTop);
  900.  
  901.         if(Style != StyleType)
  902.         {
  903.             SetSoftStyle(RPort,Style,0xFF);
  904.  
  905.             StyleType = Style;
  906.         }
  907.  
  908.         Called = FALSE;
  909.     }
  910. }
  911.  
  912.     /* ShiftChar(LONG Size):
  913.      *
  914.      *    Simulate character insertion at the current cursor
  915.      *    position by shifting the whole line Size times eight pixels
  916.      *    to the right.
  917.      */
  918.  
  919. VOID __regargs
  920. ShiftChar(LONG Size)
  921. {
  922.     LONG DeltaX,MinX,MinY;
  923.  
  924.     MinY = MUL_Y(CursorY);
  925.  
  926.     if(Config -> EmulationConfig -> FontScale == SCALE_NORMAL)
  927.     {
  928.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  929.         {
  930.             DeltaX    = MUL_X(Size);
  931.             MinX    = MUL_X(CursorX);
  932.         }
  933.         else
  934.         {
  935.             DeltaX    = MUL_X(Size) * 2;
  936.             MinX    = MUL_X(CursorX) * 2;
  937.         }
  938.     }
  939.     else
  940.     {
  941.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  942.         {
  943.             DeltaX    = MUL_X(Size) / 2;
  944.             MinX    = MUL_X(CursorX) / 2;
  945.         }
  946.         else
  947.         {
  948.             DeltaX    = MUL_X(Size);
  949.             MinX    = MUL_X(CursorX);
  950.         }
  951.     }
  952.  
  953.     if(MinX < WindowWidth)
  954.     {
  955.         BackupRender();
  956.  
  957.         ScrollLineRaster(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + TextFontHeight - 1,FALSE);
  958.  
  959.         BackupRender();
  960.     }
  961. }
  962.  
  963.     /* Ignore():
  964.      *
  965.      *    Do nothing, return immediately.
  966.      */
  967.  
  968. VOID
  969. Ignore()
  970. {
  971. }
  972.  
  973.     /* ScrollDown(STRPTR Buffer):
  974.      *
  975.      *    Scroll the current region down.
  976.      */
  977.  
  978. VOID
  979. ScrollDown(STRPTR Buffer)
  980. {
  981.     WORD Value;
  982.  
  983.     ReadValue(Buffer,&Value);
  984.  
  985.     if(Value < 1)
  986.         Value = 1;
  987.  
  988.     ScrollRegion(-Value);
  989. }
  990.  
  991.     /* ScrollUp(STRPTR Buffer):
  992.      *
  993.      *    Scroll the current region up.
  994.      */
  995.  
  996. VOID
  997. ScrollUp(STRPTR Buffer)
  998. {
  999.     WORD Value;
  1000.  
  1001.     ReadValue(Buffer,&Value);
  1002.  
  1003.     if(Value < 1)
  1004.         Value = 1;
  1005.  
  1006.     ScrollRegion(Value);
  1007. }
  1008.  
  1009.     /* CursorScrollDown():
  1010.      *
  1011.      *    Move cursor down and scroll region if necessary.
  1012.      */
  1013.  
  1014. VOID
  1015. CursorScrollDown()
  1016. {
  1017.     DownLine();
  1018.  
  1019.     ClipBlitCursor(FALSE,TRUE);
  1020. }
  1021.  
  1022. VOID
  1023. DownLine()
  1024. {
  1025.     UBYTE InRegion = TRUE;
  1026.     WORD  Hit      = LastLine;
  1027.  
  1028.     if(RegionSet)
  1029.     {
  1030.         if(CursorY <= Bottom)
  1031.             Hit = Bottom;
  1032.         else
  1033.             InRegion = FALSE;
  1034.     }
  1035.  
  1036.     if(CursorY == Hit)
  1037.     {
  1038.         if(InRegion)
  1039.             ScrollRegion(1);
  1040.     }
  1041.     else
  1042.     {
  1043.         CursorY++;
  1044.  
  1045.         if(CursorY > LastLine)
  1046.             CursorY = LastLine;
  1047.  
  1048.         ConFontScaleUpdate();
  1049.     }
  1050. }
  1051.  
  1052.     /* CursorScrollUp():
  1053.      *
  1054.      *    Move cursor up and scroll region if necessary.
  1055.      */
  1056.  
  1057. VOID
  1058. CursorScrollUp()
  1059. {
  1060.     BYTE InRegion    = TRUE;
  1061.     WORD Hit    = 0;
  1062.  
  1063.     if(RegionSet)
  1064.     {
  1065.         if(CursorY >= Top)
  1066.             Hit = Top;
  1067.         else
  1068.             InRegion = FALSE;
  1069.     }
  1070.  
  1071.     if(CursorY == Hit)
  1072.     {
  1073.         if(InRegion)
  1074.             ScrollRegion(-1);
  1075.     }
  1076.     else
  1077.     {
  1078.         if(--CursorY < 0)
  1079.             CursorY = 0;
  1080.  
  1081.         ConFontScaleUpdate();
  1082.     }
  1083.  
  1084.     ClipBlitCursor(FALSE,TRUE);
  1085. }
  1086.  
  1087.     /* NextLine():
  1088.      *
  1089.      *    Do something like CR+LF.
  1090.      */
  1091.  
  1092. VOID
  1093. NextLine()
  1094. {
  1095.     CursorX = 0;
  1096.  
  1097.     DownLine();
  1098.  
  1099.     ClipBlitCursor(FALSE,TRUE);
  1100. }
  1101.  
  1102.     /* SaveCursor():
  1103.      *
  1104.      *    Save cursor position and rendering attributes.
  1105.      */
  1106.  
  1107. VOID
  1108. SaveCursor()
  1109. {
  1110.     CursorBackup . Charset        = Charset;
  1111.     CursorBackup . Attributes    = Attributes;
  1112.     CursorBackup . CursorX        = CursorX;
  1113.     CursorBackup . CursorY        = CursorY;
  1114.     CursorBackup . Style        = StyleType;
  1115.     CursorBackup . FgPen        = GetPenIndex(ReadAPen(RPort));
  1116.     CursorBackup . BgPen        = GetPenIndex(ReadBPen(RPort));
  1117.     CursorBackup . CurrentFont    = CurrentFont;
  1118.     CursorBackup . CharMode[0]    = CharMode[0];
  1119.     CursorBackup . CharMode[1]    = CharMode[1];
  1120. }
  1121.  
  1122.     /* FontStuff(STRPTR Buffer):
  1123.      *
  1124.      *    Set the drawing font (standard characters/line).
  1125.      */
  1126.  
  1127. VOID 
  1128. FontStuff(STRPTR Buffer)
  1129. {
  1130.     BYTE Changed = FALSE;
  1131.  
  1132.     if(Buffer[0] == '(')
  1133.     {
  1134.         switch(LastChar(Buffer))
  1135.         {
  1136.             case 'A':
  1137.             case 'B':
  1138.  
  1139.                 if(CharMode[0] != TABLE_ASCII && !Charset)
  1140.                     Changed = TRUE;
  1141.  
  1142.                 CharMode[0] = TABLE_ASCII;
  1143.  
  1144.                 break;
  1145.  
  1146.             case '0':
  1147.  
  1148.                 if(CharMode[0] != TABLE_GFX && !Charset)
  1149.                     Changed = TRUE;
  1150.  
  1151.                 CharMode[0] = TABLE_GFX;
  1152.  
  1153.                 break;
  1154.         }
  1155.     }
  1156.  
  1157.     if(Buffer[0] == ')')
  1158.     {
  1159.         switch(LastChar(Buffer))
  1160.         {
  1161.             case 'A':
  1162.             case 'B':
  1163.  
  1164.                 if(CharMode[1] != TABLE_ASCII && Charset == 1)
  1165.                     Changed = TRUE;
  1166.  
  1167.                 CharMode[1] = TABLE_ASCII;
  1168.  
  1169.                 break;
  1170.  
  1171.             case '0':
  1172.  
  1173.                 if(CharMode[1] != TABLE_GFX && Charset == 1)
  1174.                     Changed = TRUE;
  1175.  
  1176.                 CharMode[1] = TABLE_GFX;
  1177.  
  1178.                 break;
  1179.         }
  1180.     }
  1181.  
  1182.     if(Changed)
  1183.     {
  1184.         BackupRender();
  1185.  
  1186.         if(Charset)
  1187.             DoShiftIn();
  1188.         else
  1189.             DoShiftOut();
  1190.  
  1191.         BackupRender();
  1192.     }
  1193. }
  1194.  
  1195.     /* LoadCursor():
  1196.      *
  1197.      *    Load cursor position and rendering attributes.
  1198.      */
  1199.  
  1200. VOID
  1201. LoadCursor()
  1202. {
  1203.     Charset        = CursorBackup . Charset;
  1204.  
  1205.     CharMode[0]    = CursorBackup . CharMode[0];
  1206.     CharMode[1]    = CursorBackup . CharMode[1];
  1207.  
  1208.     if(CurrentFont != CursorBackup . CurrentFont)
  1209.     {
  1210.         CurrentFont = CursorBackup . CurrentFont;
  1211.  
  1212.         SetFont(RPort,CurrentFont);
  1213.  
  1214.         ConOutputUpdate();
  1215.     }
  1216.  
  1217.     if(StyleType != CursorBackup . Style)
  1218.     {
  1219.         SetSoftStyle(RPort,CursorBackup . Style,0xFF);
  1220.  
  1221.         StyleType = CursorBackup . Style;
  1222.     }
  1223.  
  1224.     if(ReadAPen(RPort) != MappedPens[0][CursorBackup . FgPen])
  1225.         SetAPen(RPort,MappedPens[0][CursorBackup . FgPen]);
  1226.  
  1227.     if(ReadBPen(RPort) != MappedPens[0][CursorBackup . BgPen])
  1228.         SetBPen(RPort,MappedPens[0][CursorBackup . BgPen]);
  1229.  
  1230.     Attributes    = CursorBackup . Attributes;
  1231.     CursorX        = CursorBackup . CursorX;
  1232.     CursorY        = CursorBackup . CursorY;
  1233.  
  1234.     ConFontScaleUpdate();
  1235.  
  1236.     ClipBlitCursor(FALSE,TRUE);
  1237. }
  1238.  
  1239.     /* ScaleFont(STRPTR Buffer):
  1240.      *
  1241.      *    Select a new font scale.
  1242.      */
  1243.  
  1244. VOID 
  1245. ScaleFont(STRPTR Buffer)
  1246. {
  1247.     if(!Config -> EmulationConfig -> FontLocked)
  1248.     {
  1249.         WORD NewScale,Scale;
  1250.  
  1251.         Scale = RasterAttr[CursorY];
  1252.  
  1253.         NewScale = Scale;
  1254.  
  1255.         switch(LastChar(Buffer))
  1256.         {
  1257.             case '3':
  1258.  
  1259.                 NewScale = SCALE_ATTR_TOP2X;
  1260.  
  1261.                 break;
  1262.  
  1263.             case '4':
  1264.  
  1265.                 NewScale = SCALE_ATTR_BOT2X;
  1266.  
  1267.                 break;
  1268.  
  1269.             case '5':
  1270.  
  1271.                 NewScale = SCALE_NORMAL;
  1272.  
  1273.                 break;
  1274.  
  1275.             case '6':
  1276.  
  1277.                 NewScale = SCALE_ATTR_2X;
  1278.  
  1279.                 break;
  1280.         }
  1281.  
  1282.         if(Scale != NewScale)
  1283.         {
  1284.             UBYTE    *RasterPtr    = &Raster[CursorY * RasterWidth];
  1285.             WORD     RightMargin    = LastColumn + 1,
  1286.                  CursorXSave    = CursorX;
  1287.  
  1288.             if(NewScale != SCALE_ATTR_NORMAL)
  1289.                 RightMargin /= 2;
  1290.  
  1291.             RasterAttr[CursorY] = NewScale;
  1292.  
  1293.             ConFontScaleUpdate();
  1294.  
  1295.             if(((Config -> EmulationConfig -> FontScale == SCALE_NORMAL) && (NewScale == SCALE_ATTR_NORMAL)) || ((Config -> EmulationConfig -> FontScale == SCALE_HALF) && (NewScale == SCALE_ATTR_2X)))
  1296.             {
  1297.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(CursorY) + TextFontBase);
  1298.                 Text(RPort,RasterPtr,RightMargin);
  1299.             }
  1300.             else
  1301.             {
  1302.                 CursorX = 0;
  1303.  
  1304.                 PrintScaled(RasterPtr,RightMargin,NewScale);
  1305.             }
  1306.  
  1307.             if(CursorXSave >= RightMargin)
  1308.                 CursorX = RightMargin - 1;
  1309.             else
  1310.                 CursorX = CursorXSave;
  1311.         }
  1312.  
  1313.         ClipBlitCursor(FALSE,TRUE);
  1314.     }
  1315. }
  1316.  
  1317.     /* AlignmentTest():
  1318.      *
  1319.      *    Perform screen alignment test, fill the screen with `E's.
  1320.      */
  1321.  
  1322. VOID
  1323. AlignmentTest()
  1324. {
  1325.     STRPTR Buffer;
  1326.  
  1327.     if(Buffer = AllocVecPooled(LastColumn + 1,MEMF_ANY))
  1328.     {
  1329.         WORD i;
  1330.  
  1331.         memset(Buffer,'E',LastColumn + 1);
  1332.  
  1333.         EraseScreen("2");
  1334.  
  1335.         if(Config -> EmulationConfig -> FontScale == SCALE_HALF)
  1336.         {
  1337.             for(i = 0 ; i <= LastLine ; i++)
  1338.             {
  1339.                 CursorX = 0;
  1340.                 CursorY = i;
  1341.  
  1342.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1343.  
  1344.                 RasterPutString(Buffer,LastColumn + 1);
  1345.                 ScrollLinePutString(LastColumn + 1);
  1346.  
  1347.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1348.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  1349.             }
  1350.         }
  1351.         else
  1352.         {
  1353.             for(i = 0 ; i <= LastLine ; i++)
  1354.             {
  1355.                 CursorX = 0;
  1356.                 CursorY = i;
  1357.  
  1358.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1359.  
  1360.                 RasterPutString(Buffer,LastColumn + 1);
  1361.                 ScrollLinePutString(LastColumn + 1);
  1362.  
  1363.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1364.                 Text(RPort,Buffer,LastColumn + 1);
  1365.             }
  1366.         }
  1367.  
  1368.         CursorX = CursorY = 0;
  1369.  
  1370.         ClipBlitCursor(FALSE,TRUE);
  1371.  
  1372.         FreeVecPooled(Buffer);
  1373.  
  1374.         ConFontScaleUpdate();
  1375.     }
  1376. }
  1377.  
  1378.     /* SetTab():
  1379.      *
  1380.      *    Set a tabulator stop at the current position.
  1381.      */
  1382.  
  1383. VOID
  1384. SetTab()
  1385. {
  1386.     if(CursorX < TabStopMax)
  1387.         TabStops[CursorX] = TRUE;
  1388. }
  1389.  
  1390.     /* RequestTerminal(STRPTR Buffer):
  1391.      *
  1392.      *    Return the current terminal position.
  1393.      */
  1394.  
  1395. VOID 
  1396. RequestTerminal(STRPTR Buffer)
  1397. {
  1398.     switch(Buffer[0])
  1399.     {
  1400.             /* Make ourselves known as a VT200
  1401.              * terminal.
  1402.              */
  1403.  
  1404.         case '[':
  1405.  
  1406.             if(Buffer[1] != '>')
  1407.                 EmulationSerWrite("\033[?62;1;2;6;7;8;9c",-1);
  1408.             else
  1409.                 EmulationSerWrite("\033[>1;10;0c",-1);
  1410.  
  1411.             break;
  1412.  
  1413.             /* This is an old status request type,
  1414.              * we will return the standard `I am a
  1415.              * VT101' sequence.
  1416.              */
  1417.  
  1418.         case 'Z':
  1419.  
  1420.             EmulationSerWrite("\033[?1;0c",-1);
  1421.             break;
  1422.     }
  1423. }
  1424.  
  1425.     /* SoftReset():
  1426.      *
  1427.      *    Plain and simple: reset the text rendering colours, style and the
  1428.      *    font being used. This works similar to the Reset() call which
  1429.      *    also clears the screen.
  1430.      */
  1431.  
  1432. VOID
  1433. SoftReset()
  1434. {
  1435.     ObtainTerminal();
  1436.  
  1437.         /* Are we running on an external emulation? */
  1438.  
  1439.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1440.     {
  1441.         XEmulatorResetTextStyles(XEM_IO);
  1442.         XEmulatorResetCharset(XEM_IO);
  1443.     }
  1444.     else
  1445.     {
  1446.             /* Reset the text rendering styles. */
  1447.  
  1448.         SetAttributes("0m");
  1449.  
  1450.         if(!Config -> EmulationConfig -> FontLocked)
  1451.             Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  1452.  
  1453.         ConFontScaleUpdate();
  1454.  
  1455.             /* Reset the text rendering colours. */
  1456.  
  1457.         FgPen = GetPenIndex(SafeTextPen);
  1458.         BgPen = 0;
  1459.  
  1460.         if(ReadAPen(RPort) != MappedPens[0][FgPen])
  1461.             SetAPen(RPort,MappedPens[0][FgPen]);
  1462.  
  1463.         if(ReadBPen(RPort) != MappedPens[0][BgPen])
  1464.             SetBPen(RPort,MappedPens[0][BgPen]);
  1465.  
  1466.         SetWrMsk(RPort,DepthMask);
  1467.  
  1468.         CurrentFont = TextFont;
  1469.  
  1470.         SetFont(RPort,CurrentFont);
  1471.  
  1472.         ConOutputUpdate();
  1473.     }
  1474.  
  1475.     ReleaseTerminal();
  1476. }
  1477.  
  1478.     /* Reset():
  1479.      *
  1480.      *    Reset terminal to initial state.
  1481.      */
  1482.  
  1483. VOID
  1484. Reset()
  1485. {
  1486.     LONG    MaxColumns,MaxLines,
  1487.         Columns,Lines,
  1488.         i;
  1489.  
  1490.     ObtainTerminal();
  1491.  
  1492.     CursorEnabled = FALSE;
  1493.  
  1494.     if(Window -> Flags & WFLG_WINDOWACTIVE)
  1495.         CursorGhosted = FALSE;
  1496.     else
  1497.         CursorGhosted = TRUE;
  1498.  
  1499.         /* Determine window inner dimensions and top/left edge offsets. */
  1500.  
  1501.     WindowLeft    = Window -> BorderLeft;
  1502.     WindowTop    = Window -> BorderTop;
  1503.  
  1504.     WindowWidth    = Window -> Width - (Window -> BorderLeft + Window -> BorderRight);
  1505.     WindowHeight    = Window -> Height - (Window -> BorderTop + Window -> BorderBottom);
  1506.  
  1507.     MaxColumns    = WindowWidth / TextFontWidth;
  1508.     MaxLines    = WindowHeight / TextFontHeight;
  1509.  
  1510.         /* Set up the new screen width. */
  1511.  
  1512.     if(Config -> TerminalConfig -> NumColumns < 20)
  1513.         Columns = MaxColumns;
  1514.     else
  1515.         Columns = Config -> TerminalConfig -> NumColumns;
  1516.  
  1517.         /* Set up the new screen height. */
  1518.  
  1519.     if(Config -> TerminalConfig -> NumLines < 20)
  1520.         Lines = MaxLines;
  1521.     else
  1522.         Lines = Config -> TerminalConfig -> NumLines;
  1523.  
  1524.         /* More columns than we will be able to display? */
  1525.  
  1526.     if(Columns > MaxColumns)
  1527.         Columns = MaxColumns;
  1528.  
  1529.         /* More lines than we will be able to display? */
  1530.  
  1531.     if(Lines > MaxLines)
  1532.         Lines = MaxLines;
  1533.  
  1534.         /* Set up the central data. */
  1535.  
  1536.     LastColumn    = Columns - 1;
  1537.     LastLine    = Lines - 1;
  1538.     LastPixel    = MUL_X(Columns) - 1;
  1539.  
  1540.     memset(TabStops,FALSE,TabStopMax);
  1541.  
  1542.     for(i = 8 ; i < TabStopMax ; i += 8)
  1543.         TabStops[i] = TRUE;
  1544.  
  1545.     CharMode[0] = TABLE_ASCII;
  1546.     CharMode[1] = TABLE_GFX;
  1547.  
  1548.     Charset = 0;
  1549.  
  1550.     SetAPen(RPort,MappedPens[0][0]);
  1551.  
  1552.     SetWrMsk(RPort,DepthMask);
  1553.  
  1554.     RectFill(RPort,WindowLeft,WindowTop,WindowLeft + WindowWidth - 1,WindowTop + WindowHeight - 1);
  1555.  
  1556.     ScrollLineEraseScreen(2);
  1557.  
  1558.     RasterEraseScreen(2);
  1559.  
  1560.     FgPen = GetPenIndex(SafeTextPen);
  1561.     BgPen = 0;
  1562.  
  1563.     if(ReadAPen(RPort) != MappedPens[0][FgPen])
  1564.         SetAPen(RPort,MappedPens[0][FgPen]);
  1565.  
  1566.     if(ReadBPen(RPort) != MappedPens[0][BgPen])
  1567.         SetBPen(RPort,MappedPens[0][BgPen]);
  1568.  
  1569.     if(StyleType != FS_NORMAL)
  1570.     {
  1571.         SetSoftStyle(RPort,FS_NORMAL,0xFF);
  1572.  
  1573.         StyleType = FS_NORMAL;
  1574.     }
  1575.  
  1576.     CurrentFont = TextFont;
  1577.  
  1578.     SetFont(RPort,CurrentFont);
  1579.  
  1580.     ConOutputUpdate();
  1581.  
  1582.     UseRegion = FALSE;
  1583.     RegionSet = FALSE;
  1584.  
  1585.     if(!Config -> EmulationConfig -> CursorLocked)
  1586.         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1587.  
  1588.     if(!Config -> EmulationConfig -> KeysLocked)
  1589.         Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  1590.  
  1591.     Config -> EmulationConfig -> NewLineMode    = FALSE;
  1592.     Config -> EmulationConfig -> InsertMode        = FALSE;
  1593.  
  1594.     Config -> EmulationConfig -> LineWrap        = TRUE;
  1595.     Config -> EmulationConfig -> CursorWrap        = FALSE;
  1596.  
  1597.     Config -> EmulationConfig -> ScrollMode        = SCROLL_JUMP;
  1598.  
  1599.     if(!Config -> EmulationConfig -> FontLocked)
  1600.         Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  1601.  
  1602.     Attributes    = 0;
  1603.     Top        = 0;
  1604.     Bottom        = LastLine;
  1605.     CursorX        = 0;
  1606.     CursorY        = 0;
  1607.  
  1608.     CursorBackup . Charset        = Charset;
  1609.     CursorBackup . Attributes    = Attributes;
  1610.     CursorBackup . CursorX        = CursorX;
  1611.     CursorBackup . CursorY        = CursorY;
  1612.     CursorBackup . Style        = StyleType;
  1613.     CursorBackup . FgPen        = FgPen;
  1614.     CursorBackup . BgPen        = BgPen;
  1615.     CursorBackup . CurrentFont    = CurrentFont;
  1616.     CursorBackup . CharMode[0]    = CharMode[0];
  1617.     CursorBackup . CharMode[1]    = CharMode[1];
  1618.  
  1619.     ConFontScaleUpdate();
  1620.  
  1621.     ClipBlitCursor(FALSE,TRUE);
  1622.  
  1623.     ReleaseTerminal();
  1624. }
  1625.  
  1626.     /* PrinterController(STRPTR Buffer):
  1627.      *
  1628.      *    Controls various screen dump and capture functions.
  1629.      */
  1630.  
  1631. VOID 
  1632. PrinterController(STRPTR Buffer)
  1633. {
  1634.     if(Config -> EmulationConfig -> PrinterEnabled)
  1635.     {
  1636.         switch(Buffer[1])
  1637.         {
  1638.             case 'i':
  1639.             case '0':
  1640.  
  1641.                 if(RegionSet)
  1642.                     PrintRegion(Top,Bottom + 1);
  1643.                 else
  1644.                     PrintRegion(0,LastLine + 1);
  1645.  
  1646.                 break;
  1647.  
  1648.             case '5':
  1649.  
  1650.                 OpenPrinterCapture(TRUE);
  1651.                 break;
  1652.  
  1653.             case '4':
  1654.  
  1655.                 ClosePrinterCapture(FALSE);
  1656.                 break;
  1657.         }
  1658.     }
  1659. }
  1660.  
  1661.     /* RequestInformation(STRPTR Buffer):
  1662.      *
  1663.      *    Request miscellaneous information (state & cursor position).
  1664.      */
  1665.  
  1666. VOID 
  1667. RequestInformation(STRPTR Buffer)
  1668. {
  1669.     UBYTE    LocalBuffer[40];
  1670.     WORD    Value;
  1671.  
  1672.     ReadValue(Buffer,&Value);
  1673.  
  1674.     switch(Value)
  1675.     {
  1676.             /* Terminal status report, return code
  1677.              * for `no malfunction'.
  1678.              */
  1679.  
  1680.         case 5:
  1681.  
  1682.             EmulationSerWrite("\033[0n",-1);
  1683.             break;
  1684.  
  1685.             /* The origin is placed at 0/0 and the first
  1686.              * cursor position is 1/1. We'll have to add
  1687.              * 1 to our internal positions since our
  1688.              * universe has been shifted one field to the
  1689.              * left top corner.
  1690.              */
  1691.  
  1692.         case 6:
  1693.  
  1694.             SPrintf(LocalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1695.  
  1696.             EmulationSerWrite(LocalBuffer,-1);
  1697.  
  1698.             break;
  1699.  
  1700.             /* A VT200 command: request printer status.
  1701.              * We will return `the printer is ready' in
  1702.              * case the printer control commands are
  1703.              * enabled, else return `no printer connected'.
  1704.              */
  1705.  
  1706.         case 15:
  1707.  
  1708.             if(Config -> EmulationConfig -> PrinterEnabled)
  1709.                 EmulationSerWrite("\033[?10n",-1);
  1710.             else
  1711.                 EmulationSerWrite("\033[?11n",-1);
  1712.  
  1713.             break;
  1714.  
  1715.             /* VT200 command: request user defined
  1716.              * key status. We will return `user
  1717.              * defined keys are locked'.
  1718.              */
  1719.  
  1720.         case 25:
  1721.  
  1722.             EmulationSerWrite("\033[?21n",-1);
  1723.             break;
  1724.  
  1725.             /* Another VT200 command: request
  1726.              * keyboard language. We will return
  1727.              * `keyboard language unknown'.
  1728.              */
  1729.  
  1730.         case 26:
  1731.  
  1732.             EmulationSerWrite("\033[?27;0n",-1);
  1733.             break;
  1734.     }
  1735. }
  1736.  
  1737.     /* SetSomething(STRPTR Buffer):
  1738.      *
  1739.      *    Set a terminal option.
  1740.      */
  1741.  
  1742. VOID 
  1743. SetSomething(STRPTR Buffer)
  1744. {
  1745.     switch(Buffer[1])
  1746.     {
  1747.         case '?':
  1748.  
  1749.             switch(Buffer[2])
  1750.             {
  1751.                     /* Set cursor keys applications mode. */
  1752.  
  1753.                 case '1':
  1754.  
  1755.                     if(!Config -> EmulationConfig -> CursorLocked)
  1756.                     {
  1757.                         if(Buffer[3] == 'h')
  1758.                             Config -> EmulationConfig -> CursorMode = KEYMODE_APPLICATION;
  1759.                         else
  1760.                             Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1761.                     }
  1762.  
  1763.                     break;
  1764.  
  1765.                     /* Set line length (132 or 80). */
  1766.  
  1767.                 case '3':
  1768.  
  1769.                     if(!Config -> EmulationConfig -> FontLocked)
  1770.                     {
  1771.                         BOOLEAN TurnOn;
  1772.  
  1773.                         if(CursorEnabled)
  1774.                         {
  1775.                             ClearCursor();
  1776.  
  1777.                             TurnOn = TRUE;
  1778.                         }
  1779.                         else
  1780.                             TurnOn = FALSE;
  1781.  
  1782.                         if(Buffer[3] == 'h')
  1783.                         {
  1784.                             if(Config -> EmulationConfig -> FontScale != SCALE_HALF)
  1785.                             {
  1786.                                 CursorX = CursorY = 0;
  1787.  
  1788.                                 ClipBlitCursor(FALSE,TRUE);
  1789.  
  1790.                                 BackupRender();
  1791.  
  1792.                                 SetAPen(RPort,MappedPens[0][0]);
  1793.  
  1794.                                 ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  1795.  
  1796.                                 ScrollLineEraseScreen(2);
  1797.  
  1798.                                 RasterEraseScreen(2);
  1799.  
  1800.                                 SaveConfig(Config,PrivateConfig);
  1801.  
  1802.                                 Config -> EmulationConfig -> FontScale = SCALE_HALF;
  1803.  
  1804.                                 BackupRender();
  1805.  
  1806.                                 ScreenSizeStuff();
  1807.                             }
  1808.                         }
  1809.                         else
  1810.                         {
  1811.                             if(Config -> EmulationConfig -> FontScale != SCALE_NORMAL)
  1812.                             {
  1813.                                 CursorX = CursorY = 0;
  1814.  
  1815.                                 ClipBlitCursor(FALSE,TRUE);
  1816.  
  1817.                                 BackupRender();
  1818.  
  1819.                                 SetAPen(RPort,MappedPens[0][0]);
  1820.  
  1821.                                 ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  1822.  
  1823.                                 ScrollLineEraseScreen(2);
  1824.  
  1825.                                 RasterEraseScreen(2);
  1826.  
  1827.                                 SaveConfig(Config,PrivateConfig);
  1828.  
  1829.                                 Config -> EmulationConfig -> FontScale = SCALE_NORMAL;
  1830.  
  1831.                                 BackupRender();
  1832.  
  1833.                                 ScreenSizeStuff();
  1834.                             }
  1835.                         }
  1836.  
  1837.                         if(TurnOn)
  1838.                             DrawCursor();
  1839.                     }
  1840.  
  1841.                     break;
  1842.  
  1843.                     /* Set scroll mode (jump or smooth). */
  1844.  
  1845.                 case '4':
  1846.  
  1847.                     if(Buffer[3] == 'h')
  1848.                         Config -> EmulationConfig -> ScrollMode = SCROLL_SMOOTH;
  1849.                     else
  1850.                         Config -> EmulationConfig -> ScrollMode = SCROLL_JUMP;
  1851.  
  1852.                     break;
  1853.  
  1854.                     /* Turn region on or off. */
  1855.  
  1856.                 case '6':
  1857.  
  1858.                     if(Buffer[3] == 'h')
  1859.                         UseRegion = TRUE;
  1860.                     else
  1861.                         UseRegion = FALSE;
  1862.  
  1863.                     ResetCursor();
  1864.  
  1865.                     break;
  1866.  
  1867.                     /* Turn character wrapping on or off. */
  1868.  
  1869.                 case '7':
  1870.  
  1871.                     if(Buffer[3] == 'h')
  1872.                         Config -> EmulationConfig -> LineWrap = TRUE;
  1873.                     else
  1874.                         Config -> EmulationConfig -> LineWrap = FALSE;
  1875.  
  1876.                     break;
  1877.  
  1878.                     /* Set interlaced mode. */
  1879.  
  1880.                 case '9':
  1881.  
  1882.                     if(Buffer[3] == 'h')
  1883.                     {
  1884.                         if(!(Config -> ScreenConfig -> DisplayMode & LACE))
  1885.                         {
  1886.                             if(!ModeNotAvailable(Config -> ScreenConfig -> DisplayMode | LACE))
  1887.                             {
  1888.                                 SaveConfig(Config,PrivateConfig);
  1889.  
  1890.                                 Config -> ScreenConfig -> DisplayMode |= LACE;
  1891.  
  1892.                                 ResetDisplay = TRUE;
  1893.                             }
  1894.                         }
  1895.                     }
  1896.                     else
  1897.                     {
  1898.                         if(Config -> ScreenConfig -> DisplayMode & LACE)
  1899.                         {
  1900.                             if(!ModeNotAvailable(Config -> ScreenConfig -> DisplayMode & ~LACE))
  1901.                             {
  1902.                                 SaveConfig(Config,PrivateConfig);
  1903.  
  1904.                                 Config -> ScreenConfig -> DisplayMode &= ~LACE;
  1905.  
  1906.                                 ResetDisplay = TRUE;
  1907.                             }
  1908.                         }
  1909.                     }
  1910.  
  1911.                     break;
  1912.             }
  1913.  
  1914.             break;
  1915.  
  1916.         case '2':
  1917.  
  1918.                 /* Set newline mode. */
  1919.  
  1920.             if(Buffer[2] == '0')
  1921.             {
  1922.                 if(Buffer[3] == 'h')
  1923.                     Config -> EmulationConfig -> NewLineMode = TRUE;
  1924.                 else
  1925.                     Config -> EmulationConfig -> NewLineMode = FALSE;
  1926.             }
  1927.  
  1928.             break;
  1929.  
  1930.         case '4':
  1931.  
  1932.                 /* Set insert mode. */
  1933.  
  1934.             if(Buffer[2] == 'h')
  1935.                 Config -> EmulationConfig -> InsertMode = TRUE;
  1936.             else
  1937.                 Config -> EmulationConfig -> InsertMode = FALSE;
  1938.  
  1939.             break;
  1940.  
  1941.         case '1':
  1942.  
  1943.                 /* Print region or screen. */
  1944.  
  1945.             if(Buffer[2] == '9')
  1946.             {
  1947.                 if(Buffer[3] == 'l')
  1948.                 {
  1949.                     if(RegionSet)
  1950.                         PrintRegion(Top,Bottom + 1);
  1951.                     else
  1952.                         PrintRegion(0,LastLine + 1);
  1953.                 }
  1954.  
  1955.                 if(Buffer[3] == 'h')
  1956.                     PrintRegion(0,LastLine + 1);
  1957.             }
  1958.  
  1959.             break;
  1960.  
  1961.         default:
  1962.  
  1963.             break;
  1964.     }
  1965. }
  1966.  
  1967.     /* NumericAppMode(STRPTR Buffer):
  1968.      *
  1969.      *    Set the numeric pad applications mode.
  1970.      */
  1971.  
  1972. VOID 
  1973. NumericAppMode(STRPTR Buffer)
  1974. {
  1975.     if(!Config -> EmulationConfig -> KeysLocked)
  1976.     {
  1977.         if(*Buffer == '=')
  1978.             Config -> EmulationConfig -> NumericMode = KEYMODE_APPLICATION;
  1979.         else
  1980.         {
  1981.             if(*Buffer == '>')
  1982.                 Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  1983.         }
  1984.     }
  1985. }
  1986.  
  1987.     /* MoveCursor(STRPTR Buffer):
  1988.      *
  1989.      *    Move the cursor in some direction and stop at
  1990.      *    top/bottom/margin if necessary.
  1991.      */
  1992.  
  1993. VOID 
  1994. MoveCursor(STRPTR Buffer)
  1995. {
  1996.     WORD Value,Hit,LastCharPosition;
  1997.     BYTE InRegion = TRUE;
  1998.  
  1999.     ReadValue(Buffer,&Value);
  2000.  
  2001.     if(Value < 1)
  2002.         Value = 1;
  2003.  
  2004.     switch(LastChar(Buffer))
  2005.     {
  2006.             /* Move cursor Up value lines */
  2007.  
  2008.         case 'A':
  2009.  
  2010. ScrollUp:        Hit = 0;
  2011.  
  2012.             if(RegionSet)
  2013.             {
  2014.                 if(CursorY >= Top)
  2015.                     Hit = Top;
  2016.                 else
  2017.                     InRegion = FALSE;
  2018.             }
  2019.  
  2020.             CursorY -= Value;
  2021.  
  2022.             if(CursorY < Hit)
  2023.             {
  2024.                 Value = CursorY - Hit;
  2025.  
  2026.                 CursorY = Hit;
  2027.  
  2028.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2029.                     ScrollRegion(Value);
  2030.             }
  2031.  
  2032.             ConFontScaleUpdate();
  2033.  
  2034.             break;
  2035.  
  2036.             /* Move cursor Down value lines */
  2037.  
  2038.         case 'B':
  2039.  
  2040. ScrollDown:        Hit = LastLine;
  2041.  
  2042.             if(RegionSet)
  2043.             {
  2044.                 if(CursorY <= Bottom)
  2045.                     Hit = Bottom;
  2046.                 else
  2047.                     InRegion = FALSE;
  2048.             }
  2049.  
  2050.             CursorY += Value;
  2051.  
  2052.             if(CursorY > Hit)
  2053.             {
  2054.                 Value = CursorY - Hit;
  2055.  
  2056.                 CursorY = Hit;
  2057.  
  2058.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2059.                     ScrollRegion(Value);
  2060.             }
  2061.  
  2062.             ConFontScaleUpdate();
  2063.  
  2064.             break;
  2065.  
  2066.             /* Move cursor Right value columns */
  2067.  
  2068.         case 'C':
  2069.  
  2070.             CursorX += Value;
  2071.  
  2072.             if(CursorX > LastColumn)
  2073.             {
  2074.                 if(Config -> EmulationConfig -> CursorWrap)
  2075.                 {
  2076.                     Value     = CursorX / (LastColumn + 1);
  2077.  
  2078.                     CursorX    -= Value * (LastColumn + 1);
  2079.  
  2080.                     goto ScrollDown;
  2081.                 }
  2082.                 else
  2083.                     CursorX = LastColumn;
  2084.             }
  2085.  
  2086.             break;
  2087.  
  2088.             /* Move cursor Left value columns */
  2089.  
  2090.         case 'D':
  2091.  
  2092.             CursorX -= Value;
  2093.  
  2094.             if(CursorX < 0)
  2095.             {
  2096.                 if(Config -> EmulationConfig -> CursorWrap)
  2097.                 {
  2098.                     Value     = CursorX / (LastColumn + 1);
  2099.                     CursorX    -= Value * (LastColumn + 1);
  2100.                     Value     = -Value;
  2101.  
  2102.                     goto ScrollDown;
  2103.                 }
  2104.                 else
  2105.                     CursorX = 0;
  2106.             }
  2107.  
  2108.             break;
  2109.     }
  2110.  
  2111.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  2112.         LastCharPosition = LastColumn;
  2113.     else
  2114.         LastCharPosition = ((LastColumn + 1) / 2) - 1;
  2115.  
  2116.     if(CursorX > LastCharPosition)
  2117.         CursorX = LastCharPosition;
  2118.  
  2119.     ClipBlitCursor(FALSE,TRUE);
  2120. }
  2121.  
  2122.     /* MoveColumn(STRPTR Buffer):
  2123.      *
  2124.      *    Move the cursor to a certain column.
  2125.      */
  2126.  
  2127. VOID 
  2128. MoveColumn(STRPTR Buffer)
  2129. {
  2130.     WORD Value,LastCharPosition;
  2131.  
  2132.     ReadValue(Buffer,&Value);
  2133.  
  2134.     if(Value < 1)
  2135.         Value = 1;
  2136.  
  2137.     CursorX = Value - 1;
  2138.  
  2139.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  2140.         LastCharPosition = LastColumn;
  2141.     else
  2142.         LastCharPosition = ((LastColumn + 1) / 2) - 1;
  2143.  
  2144.     if(CursorX > LastColumn)
  2145.         CursorX = LastColumn;
  2146.  
  2147.     if(CursorX > LastCharPosition)
  2148.         CursorX = LastCharPosition;
  2149.  
  2150.     ClipBlitCursor(FALSE,TRUE);
  2151. }
  2152.  
  2153.     /* EraseLine(STRPTR Buffer):
  2154.      *
  2155.      *    Erase a line on the display.
  2156.      */
  2157.  
  2158. VOID 
  2159. EraseLine(STRPTR Buffer)
  2160. {
  2161.     WORD Value,Width = GetFontWidth();
  2162.  
  2163.     ReadValue(Buffer,&Value);
  2164.  
  2165.     BackupRender();
  2166.  
  2167.     SetAPen(RPort,MappedPens[0][0]);
  2168.  
  2169.     switch(Value)
  2170.     {
  2171.         case 1:
  2172.  
  2173.             ScrollLineRectFill(RPort,0,MUL_Y(CursorY),((CursorX + 1) * Width) - 1,MUL_Y(CursorY + 1) - 1);
  2174.             break;
  2175.  
  2176.         case 2:
  2177.  
  2178.             ScrollLineRectFill(RPort,0,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2179.             break;
  2180.  
  2181.         default:
  2182.  
  2183.             ScrollLineRectFill(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2184.             break;
  2185.     }
  2186.  
  2187.     ScrollLineEraseLine(Value);
  2188.  
  2189.     RasterEraseLine(Value);
  2190.  
  2191.     BackupRender();
  2192. }
  2193.  
  2194.     /* EraseScreen(STRPTR Buffer):
  2195.      *
  2196.      *    Erase parts of the screen.
  2197.      */
  2198.  
  2199. VOID 
  2200. EraseScreen(STRPTR Buffer)
  2201. {
  2202.     WORD Value,Width = GetFontWidth();
  2203.  
  2204.     ReadValue(Buffer,&Value);
  2205.  
  2206.     BackupRender();
  2207.  
  2208.     SetAPen(RPort,MappedPens[0][0]);
  2209.  
  2210.     switch(Value)
  2211.     {
  2212.         case 1:
  2213.  
  2214.             if(CursorY)
  2215.                 ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(CursorY) - 1);
  2216.  
  2217.             ScrollLineRectFill(RPort,0,MUL_Y(TextFontHeight),((CursorX + 1) * Width) - 1,MUL_Y(CursorY + 1) - 1);
  2218.  
  2219.             break;
  2220.  
  2221.         case 2:
  2222.  
  2223.             ScrollLineRectFill(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2224.  
  2225.             if(Config -> EmulationConfig -> CLSResetsCursor)
  2226.                 CursorX = CursorY = 0;
  2227.  
  2228.             break;
  2229.  
  2230.         default:
  2231.  
  2232.             ScrollLineRectFill(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2233.  
  2234.             if(CursorY != LastLine)
  2235.                 ScrollLineRectFill(RPort,0,MUL_Y(CursorY + 1),LastPixel,MUL_Y(LastLine + 1) - 1);
  2236.  
  2237.             break;
  2238.     }
  2239.  
  2240.     ScrollLineEraseScreen(Value);
  2241.  
  2242.     RasterEraseScreen(Value);
  2243.  
  2244.     BackupRender();
  2245. }
  2246.  
  2247.     /* EraseCharacters(STRPTR Buffer):
  2248.      *
  2249.      *    Erase a number of characters.
  2250.      */
  2251.  
  2252. VOID 
  2253. EraseCharacters(STRPTR Buffer)
  2254. {
  2255.     WORD Value,Width = GetFontWidth();
  2256.  
  2257.     ReadValue(Buffer,&Value);
  2258.  
  2259.     BackupRender();
  2260.  
  2261.     if(Value < 1)
  2262.         Value = 1;
  2263.  
  2264.     RasterEraseCharacters(Value);
  2265.  
  2266.     ScrollLineEraseCharacters(Value);
  2267.  
  2268.     ScrollLineRaster(RPort,Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2269.  
  2270.     BackupRender();
  2271. }
  2272.  
  2273.     /* InsertCharacters(STRPTR Buffer):
  2274.      *
  2275.      *    Insert a number of characters.
  2276.      */
  2277.  
  2278. VOID 
  2279. InsertCharacters(STRPTR Buffer)
  2280. {
  2281.     WORD Value,Width = GetFontWidth();
  2282.  
  2283.     ReadValue(Buffer,&Value);
  2284.  
  2285.     BackupRender();
  2286.  
  2287.     if(Value < 1)
  2288.         Value = 1;
  2289.  
  2290.     RasterShiftChar(Value);
  2291.  
  2292.     ScrollLineShiftChar(Value);
  2293.  
  2294.     ScrollLineRaster(RPort,-Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2295.  
  2296.     BackupRender();
  2297. }
  2298.  
  2299.     /* InsertLine(STRPTR Buffer):
  2300.      *
  2301.      *    Insert a number of lines and scroll the rest of the
  2302.      *    display down.
  2303.      */
  2304.  
  2305. VOID 
  2306. InsertLine(STRPTR Buffer)
  2307. {
  2308.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2309.  
  2310.     ReadValue(Buffer,&Value);
  2311.  
  2312.     BackupRender();
  2313.  
  2314.     SetAPen(RPort,MappedPens[0][0]);
  2315.  
  2316.     if(Value < 1)
  2317.         Value = 1;
  2318.  
  2319.     if(RegionSet)
  2320.     {
  2321.         RegionTop    = Top;
  2322.         RegionBottom    = Bottom + 1;
  2323.     }
  2324.     else
  2325.     {
  2326.         RegionTop    = 0;
  2327.         RegionBottom    = LastLine + 1;
  2328.     }
  2329.  
  2330.     if(TheTop < RegionTop)
  2331.         TheTop = RegionTop;
  2332.  
  2333.     RasterInsertLine(Value,TheTop);
  2334.  
  2335.     ScrollLineRaster(RPort,0,-MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2336.  
  2337.     BackupRender();
  2338. }
  2339.  
  2340.     /* ClearLine(STRPTR Buffer):
  2341.      *
  2342.      *    Clear a number of lines and scroll up the ones below it.
  2343.      */
  2344.  
  2345. VOID 
  2346. ClearLine(STRPTR Buffer)
  2347. {
  2348.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2349.  
  2350.     ReadValue(Buffer,&Value);
  2351.  
  2352.     BackupRender();
  2353.  
  2354.     SetAPen(RPort,MappedPens[0][0]);
  2355.  
  2356.     if(Value < 1)
  2357.         Value = 1;
  2358.  
  2359.     if(RegionSet)
  2360.     {
  2361.         RegionTop    = Top;
  2362.         RegionBottom    = Bottom + 1;
  2363.     }
  2364.     else
  2365.     {
  2366.         RegionTop    = 0;
  2367.         RegionBottom    = LastLine + 1;
  2368.     }
  2369.  
  2370.     if(TheTop < RegionTop)
  2371.         TheTop = RegionTop;
  2372.  
  2373.     RasterClearLine(Value,TheTop);
  2374.  
  2375.     ScrollLineRaster(RPort,0,MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2376.  
  2377.     BackupRender();
  2378. }
  2379.  
  2380.     /* SetTabs(STRPTR Buffer):
  2381.      *
  2382.      *    Set the current tab stops.
  2383.      */
  2384.  
  2385. VOID 
  2386. SetTabs(STRPTR Buffer)
  2387. {
  2388.     WORD Value;
  2389.  
  2390.     ReadValue(Buffer,&Value);
  2391.  
  2392.     if(Value < 1)
  2393.         Value = 0;
  2394.  
  2395.     switch(Value)
  2396.     {
  2397.         case 0:
  2398.  
  2399.             if(CursorX < TabStopMax)
  2400.                 TabStops[CursorX] = FALSE;
  2401.  
  2402.             break;
  2403.  
  2404.         case 3:
  2405.  
  2406.             memset(TabStops,FALSE,TabStopMax);
  2407.  
  2408.             break;
  2409.  
  2410.         default:
  2411.  
  2412.             break;
  2413.     }
  2414. }
  2415.  
  2416.     /* SetAbsolutePosition(STRPTR Buffer):
  2417.      *
  2418.      *    Move the cursor to a given location on the display,
  2419.      *    this routine ignores the current scroll region
  2420.      *    settings.
  2421.      */
  2422.  
  2423. VOID 
  2424. SetAbsolutePosition(STRPTR Buffer)
  2425. {
  2426.     WORD Value;
  2427.  
  2428.     Buffer = ReadValue(Buffer,&Value);
  2429.  
  2430.     if(UseRegion && RegionSet)
  2431.         CursorY = Top;
  2432.     else
  2433.         CursorY = 0;
  2434.  
  2435.     CursorX = 0;
  2436.  
  2437.     if(Value != -1)
  2438.     {
  2439.             /* Our raster origin is 0/0 instead of 1/1. */
  2440.  
  2441.         if(Value)
  2442.             Value--;
  2443.  
  2444.         if(UseRegion && RegionSet)
  2445.             CursorY = Top + Value;
  2446.         else
  2447.             CursorY = Value;
  2448.  
  2449.         if(Buffer)
  2450.         {
  2451.             ReadValue(Buffer,&Value);
  2452.  
  2453.             if(Value > 0)
  2454.                 CursorX = Value - 1;
  2455.             else
  2456.                 CursorX = 0;
  2457.         }
  2458.  
  2459.             /* Truncate illegal positions. */
  2460.  
  2461.         if(CursorX > LastColumn)
  2462.             CursorX = LastColumn;
  2463.  
  2464.         if(CursorY > LastLine)
  2465.             CursorY = LastLine;
  2466.     }
  2467.  
  2468.     ConFontScaleUpdate();
  2469.  
  2470.     ClipBlitCursor(FALSE,TRUE);
  2471. }
  2472.  
  2473.     /* SetAttributes(STRPTR Buffer):
  2474.      *
  2475.      *    Set the current display rendering attributes.
  2476.      */
  2477.  
  2478. VOID 
  2479. SetAttributes(STRPTR Buffer)
  2480. {
  2481.     LONG TextFlags = FS_NORMAL;
  2482.     WORD Value;
  2483.  
  2484.     do
  2485.     {
  2486.         Buffer = ReadValue(Buffer,&Value);
  2487.  
  2488.         if(Value == -1)
  2489.             Value = 0;
  2490.  
  2491.         switch(Value)
  2492.         {
  2493.             case 0:
  2494.  
  2495.                 FgPen = GetPenIndex(SafeTextPen);
  2496.                 BgPen = 0;
  2497.  
  2498.                 Attributes = 0;
  2499.  
  2500.                 break;
  2501.  
  2502.             case 1:
  2503.  
  2504.                 Attributes |= ATTR_HIGHLIGHT;
  2505.  
  2506.                 break;
  2507.  
  2508.             case 4:
  2509.  
  2510.                 Attributes |= ATTR_UNDERLINE;
  2511.  
  2512.                 break;
  2513.  
  2514.             case 5:
  2515.  
  2516.                 Attributes |= ATTR_BLINK;
  2517.  
  2518.                 break;
  2519.  
  2520.             case 7:
  2521.  
  2522.                 if(!(Attributes & ATTR_INVERSE))
  2523.                 {
  2524.                     BYTE Help;
  2525.  
  2526.                     Help    = FgPen;
  2527.                     FgPen    = BgPen;
  2528.                     BgPen    = Help;
  2529.                 }
  2530.  
  2531.                 Attributes |= ATTR_INVERSE;
  2532.  
  2533.                 break;
  2534.  
  2535.             default:
  2536.  
  2537.                 if(Value >= 30)
  2538.                 {
  2539.                     if(Value <= 37)
  2540.                     {
  2541.                         if(Attributes & ATTR_INVERSE)
  2542.                             BgPen = Value - 30;
  2543.                         else
  2544.                             FgPen = Value - 30;
  2545.                     }
  2546.                     else
  2547.                     {
  2548.                         if(Value >= 40 && Value <= 47)
  2549.                         {
  2550.                             if(Attributes & ATTR_INVERSE)
  2551.                                 FgPen = Value - 40;
  2552.                             else
  2553.                                 BgPen = Value - 40;
  2554.                         }
  2555.                     }
  2556.                 }
  2557.  
  2558.                 break;
  2559.         }
  2560.     }
  2561.     while(Buffer);
  2562.  
  2563.         /* Make sure that the text rendered will be
  2564.          * visible by wrapping the colour if
  2565.          * necessary.
  2566.          */
  2567.  
  2568.     if(FgPen > DepthMask && !(FgPen & DepthMask))
  2569.         FgPen = GetPenIndex(SafeTextPen);
  2570.  
  2571.     if(BgPen > DepthMask && !(BgPen & DepthMask))
  2572.         BgPen = GetPenIndex(SafeTextPen);
  2573.  
  2574.     if(Attributes & ATTR_UNDERLINE)
  2575.         TextFlags |= FSF_UNDERLINED;
  2576.  
  2577.     if(Attributes & ATTR_HIGHLIGHT)
  2578.     {
  2579.         if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)
  2580.         {
  2581.             if(Attributes & ATTR_INVERSE)
  2582.                 BgPen |= 8;
  2583.             else
  2584.                 FgPen |= 8;
  2585.         }
  2586.         else
  2587.             TextFlags |= FSF_BOLD;
  2588.     }
  2589.  
  2590.     if(Attributes & ATTR_BLINK)
  2591.     {
  2592.         if(Config -> TerminalConfig -> EmulationMode == EMULATION_ANSIVT100)
  2593.         {
  2594.             switch(Config -> ScreenConfig -> ColourMode)
  2595.             {
  2596.                 case COLOUR_AMIGA:
  2597.  
  2598.                     if(Attributes & ATTR_INVERSE)
  2599.                         BgPen = 3;
  2600.                     else
  2601.                         FgPen = 3;
  2602.  
  2603.                     break;
  2604.  
  2605.                 case COLOUR_EIGHT:
  2606.  
  2607.                     if(Attributes & ATTR_INVERSE)
  2608.                         BgPen |= 8;
  2609.                     else
  2610.                         FgPen |= 8;
  2611.  
  2612.                     break;
  2613.  
  2614.                 case COLOUR_SIXTEEN:
  2615.  
  2616.                     if(Screen)
  2617.                     {
  2618.                         if(Screen -> RastPort . BitMap -> Depth > 4)
  2619.                         {
  2620.                             if(Attributes & ATTR_INVERSE)
  2621.                                 BgPen |= 16;
  2622.                             else
  2623.                                 FgPen |= 16;
  2624.                         }
  2625.                     }
  2626.  
  2627.                     break;
  2628.  
  2629.                 case COLOUR_MONO:
  2630.  
  2631.                     if(Attributes & ATTR_INVERSE)
  2632.                         BgPen = GetPenIndex(SafeTextPen);
  2633.                     else
  2634.                         FgPen = GetPenIndex(SafeTextPen);
  2635.  
  2636.                     break;
  2637.             }
  2638.         }
  2639.     }
  2640.  
  2641.     if(TextFlags != StyleType)
  2642.     {
  2643.         SetSoftStyle(RPort,TextFlags,0xFF);
  2644.  
  2645.         StyleType = TextFlags;
  2646.     }
  2647.  
  2648.     if(Config -> ScreenConfig -> ColourMode == COLOUR_MONO)
  2649.     {
  2650.         if(ColourValue(MappedPens[0][FgPen]) < ColourValue(MappedPens[0][BgPen]))
  2651.         {
  2652.             if(Attributes & ATTR_INVERSE)
  2653.             {
  2654.                 FgPen = GetPenIndex(SafeTextPen);
  2655.                 BgPen = 0;
  2656.             }
  2657.             else
  2658.             {
  2659.                 FgPen = 0;
  2660.                 BgPen = GetPenIndex(SafeTextPen);
  2661.             }
  2662.         }
  2663.         else
  2664.         {
  2665.             if(Attributes & ATTR_INVERSE)
  2666.             {
  2667.                 FgPen = 0;
  2668.                 BgPen = GetPenIndex(SafeTextPen);
  2669.             }
  2670.             else
  2671.             {
  2672.                 FgPen = GetPenIndex(SafeTextPen);
  2673.                 BgPen = 0;
  2674.             }
  2675.         }
  2676.     }
  2677.  
  2678.     if(MappedPens[0][FgPen] != ReadAPen(RPort))
  2679.         SetAPen(RPort,MappedPens[0][FgPen]);
  2680.  
  2681.     if(MappedPens[0][BgPen] != ReadBPen(RPort))
  2682.         SetBPen(RPort,MappedPens[0][BgPen]);
  2683.  
  2684.     ClipBlitCursor(FALSE,TRUE);
  2685. }
  2686.  
  2687.     /* SetRegion(STRPTR Buffer):
  2688.      *
  2689.      *    Set the current scroll region top and bottom.
  2690.      */
  2691.  
  2692. VOID 
  2693. SetRegion(STRPTR Buffer)
  2694. {
  2695.     WORD NewTop,Value,NewBottom = LastLine;
  2696.  
  2697.     Buffer = ReadValue(Buffer,&Value);
  2698.  
  2699.     if(!Value)
  2700.         Value = 1;
  2701.  
  2702.     if(Value > 0)
  2703.     {
  2704.         if(Buffer)
  2705.         {
  2706.             NewTop = Value - 1;
  2707.  
  2708.             ReadValue(Buffer,&Value);
  2709.  
  2710.             if(Value > 0)
  2711.                 NewBottom = Value - 1;
  2712.  
  2713.             if(NewBottom > LastLine)
  2714.                 NewBottom = LastLine;
  2715.  
  2716.             if(NewTop > LastLine)
  2717.                 NewTop = LastLine;
  2718.         }
  2719.         else
  2720.         {
  2721.             NewTop        = 0;
  2722.             NewBottom    = LastLine;
  2723.         }
  2724.     }
  2725.     else
  2726.     {
  2727.         NewTop        = 0;
  2728.         NewBottom    = LastLine;
  2729.     }
  2730.  
  2731.     if(NewTop < NewBottom)
  2732.     {
  2733.         if(NewTop != 0 || NewBottom != LastLine)
  2734.         {
  2735.             Top    = NewTop;
  2736.             Bottom    = NewBottom;
  2737.  
  2738.             RegionSet = TRUE;
  2739.         }
  2740.         else
  2741.             UseRegion = RegionSet = FALSE;
  2742.  
  2743.         ResetCursor();
  2744.     }
  2745.     else
  2746.         RegionSet = FALSE;
  2747. }
  2748.  
  2749.     /* ResetCursor():
  2750.      *
  2751.      *    Reset cursor to top of screen.
  2752.      */
  2753.  
  2754. VOID
  2755. ResetCursor()
  2756. {
  2757.     CursorX    = 0;
  2758.  
  2759.     if(UseRegion && RegionSet)
  2760.         CursorY = Top;
  2761.     else
  2762.         CursorY    = 0;
  2763.  
  2764.     ConFontScaleUpdate();
  2765.  
  2766.     ClipBlitCursor(FALSE,TRUE);
  2767. }
  2768.